[기초] JNI (Java-C 연동)
NOTE
Java-C 연동(JNI) 환경설정, so 파일 생성/확인, DLL 개념, gcc로 공유 라이브러리 만들기 정리.
🖥️ 시스템/환경
- JDK 관리:
alternatives(Linux 계열, 여러 JDK 버전을 시스템 차원에서 전환)
📋 작업 내역
JAVA 환경설정
/etc/bashrc- JAVA_HOME 설정:
export JAVA_HOME=/usr/lib/jvm/[jdk버전 디렉토리] - LD_LIBRARY_PATH 설정:
export LD_LIBRARY_PATH=$JAVA_HOME:$JAVA_HOME/include:$JAVA_HOME/include/linux:/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib
- JAVA_HOME 설정:
- JAVA JDK 설정
- 현재 설정 확인:
alternatives --list - 설정 변경:
alternatives --config java,alternatives --config javac
- 현재 설정 확인:
C to JAVA library
- 헤더파일 만들기:
javac -h . <소스파일> - c 파일 → so 파일 만들기:
gcc -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -shared -fpic -o libexample.so example.c
NOTE
so 파일 심볼 확인 →
nm [파일명].so로 라이브러리가 내보내는 함수(예:Java_패키지_클래스_메서드)가 정상적으로 포함됐는지 확인 가능
NOTE
링크파일(의존성 확인) →
ldd [파일명].[확장자]로 공유 라이브러리 의존성이 모두 해석되는지 확인
- 실행:
java -Djava.library.path=. NativeUtils(외부 라이브러리이므로 경로를 지정해서 실행해야 함)
자주 겪는 오류
- 증상:
int NativeUtils.multiplyNumbers(int, int) → LinkError,Caused by: java.lang.NoClassDefFoundError - 원인:
LD_LIBRARY_PATH에 so 파일이 위치한 작업 경로가 빠져있는 경우가 대부분export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$JAVA_HOME:$JAVA_HOME/include:$JAVA_HOME/include/linux:[so파일 위치 디렉토리]
DLL(Windows)
- 외부 라이브러리 / 동적 링크 라이브러리
__declspec(dllexport): 외부로 보여주기 위한 함수 선언__declspec(dllimport): 내부에서 사용 목적으로 선언- 과정: dll 만들기 → h(헤더) 만들기 → 컴파일 ⇒ lib + dll 파일 → new 프로젝트에서 cpp 연동 및 빌드 ⇒ release 파일 실행
gcc로 so 파일 만들기(Linux)
- c file(
~.c)gcc -c ~.c// compile → 결과:~.o(목적파일 생성)
- dynamic 라이브러리 만들기:
gcc -shared (-fPIC) -o [라이브러리명].so [목적파일명].o - LD_LIBRARY_PATH 설정이 안 되면
/usr/lib에 so 파일을 직접 복사하는 방법도 있음 - MAIN file:
gcc -o [out 파일명] [main.c] -l [라이브러리명] -L [라이브러리 경로]- 예)
libhello.so⇒ 라이브러리명: hello
- 예)
📌 비고
- Windows DLL 생성/의존성 이슈 대응은 원문에서 “구체적으로 파악 필요”로 남겨져 있던 부분이라, 추가 검증 후 보강 필요.